package com.org.khtn.data;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Vector;

import com.google.gson.Gson;

/**
 * 
 * @author Son
 * 
 */
public class Table {
	private final String className = "Table:";
	Fields _fields;
	String _name;
	String[] primaryKey;
	Map<String, Map<String, String>> data;

	public Table(Fields field, String name) {
		_fields = field;
		_name = name;
		data = new HashMap<String, Map<String, String>>();
	}

	public String getAllFieldName() {
		final String methodName = "getAllFieldName():";
		String result = _fields.getAllFieldName();
		System.out.println(className + methodName + "result: " + result);
		return result;
	}

	public Fields getFields() {
		return _fields;
	}

	public int size() {
		return data.size();
	}

	public String getName() {
		return _name;
	}

	public Boolean fieldExit(String name) {
		return _fields.exist(name);
	}

	public void setData() {
		_fields.getData(data);
	}

	public void renameField(String fieldName, String fieldNameNew) {
		_fields.rename(fieldName, fieldNameNew);
	}

	public void addField(String fieldName, String fieldType) {
		_fields.add(new Field(fieldName, fieldType));
	}

	public void setData(Map<String, Map<String, String>> Data) {
		final String methodName = "setData()";
		data = Data;
		// // System.out.println(className +":"+methodName+":"+data );

	}

	public Map<String, Map<String, String>> getData() {

		return data;
	}

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return data.toString();
	}

	public void editValueAllRecord(String fieldName, String value) {
		final String methodName = "editValueAllRecord:";
		if (data == null)
			return;
		int length = data.size();
		System.out.println(className + methodName + "data:" + data);
		System.out.println("Table : editValueAllRecord() : length " + length);
		for (Map.Entry<String, Map<String, String>> dd : data.entrySet()) {
			Map<String, Map<String, String>> a = new HashMap<String, Map<String, String>>();
			Map<String, String> temp = new HashMap<String, String>();

			temp.putAll(dd.getValue());
			temp.put(fieldName, value);
			a.put(dd.getKey(), temp);
			// // System.out.println(className+methodName+"a:"+a);

			data.put(dd.getKey(), a.get(dd.getKey()));
		}

	}

	/**
	 * xóa data của 1 field trong table
	 * 
	 * @param fieldName
	 */

	public Map<String, Map<String, String>> getRow(int idx) {
		final String methodName = "getRow():";
		int length = data.size();
		Map<String, Map<String, String>> result = new HashMap<String, Map<String, String>>();

		if (idx < 0 || idx > length - 1)
			return null;

		for (Map.Entry<String, Map<String, String>> e : data.entrySet()) {
			// // System.out.println("Table : getRow() : e.getKey " +
			// e.getKey());
			if (Integer.parseInt(e.getKey()) == idx) {
				result.put(e.getKey(), e.getValue());

			}
		}
		// // System.out.println(className+methodName+"result:"+result);
		return result;

	}

	/**
	 * tráº£ vá»� dÃ²ng cÃ³ field = value
	 * 
	 * @param fieldName
	 * @param value
	 * @return
	 */
	public Map<String, Map<String, String>> getRow(String fieldName,
			String value) {
		Map<String, Map<String, String>> result = new HashMap<String, Map<String, String>>();

		for (Map.Entry<String, Map<String, String>> e : data.entrySet()) {
			Map<String, String> temp = e.getValue();
			if (e.getValue().get(fieldName).equals(value)) {
				result.put(e.getKey(), e.getValue());
			}
		}
		return result;

	}

	public void createField(String fieldName, String fieldType) {
		// TODO Auto-generated method stubf
		final String methodName = "createField():";
		if (_fields == null) {
			_fields = new Fields();
		}
		System.out.println(className + methodName + "_fields.size 1 :"
				+ _fields.size());

		addField(fieldName, fieldType);
		System.out.println(className + methodName + "_fields.size 2 :"
				+ _fields.size());

	}

	public String getAllTypes() {
		return _fields.getAllTypes();
		// TODO Auto-generated method stub

	}

	public void editField(String fieldName, String fieldType) {
		// TODO Auto-generated method stub
		_fields.edit(fieldName, fieldType);

	}

	public boolean isPrimaryKey(String fieldName) {
		if (primaryKey == null)
			return false;
		int length = primaryKey.length;
		for (int i = 0; i < length; i++)
			if (primaryKey[i].equalsIgnoreCase(fieldName))
				return true;
		return false;
	}

	public Map<String, Map<String, String>> getAllRow() {
		// TODO Auto-generated method stub

		Map<String, Map<String, String>> result = new HashMap<String, Map<String, String>>();
		if (data == null) {
			return null;
		}
		result.putAll(data);
		return result;
	}

	public int insertRecord(String[] fieldName, String[] fieldValue) {
		// TODO Auto-generated method stub
		final String methodName = "insertRecord():";
		Vector primaryKey = getPrimaryKey();
		if (data == null)
			data = new HashMap<String, Map<String, String>>();
		int length = data.size();
		int length1 = fieldName.length;
		System.out.println(className + methodName + "data 0: " + data);

		Map<String, String> temp = new HashMap<String, String>();
		Map<String, String> dub = new HashMap<String, String>();
		for (Map.Entry<String, Map<String, String>> da : data.entrySet()) {
			String tam = "";
			for (int i = 0; i < length1; i++) {
				if (isPrimaryKey(fieldName[i]))
					tam += da.getValue().get(fieldName[i]);
			}
			if (tam != "")
				dub.put(tam, "");
		}
		String tam = "";
		int max = 0;
		for (Map.Entry<String, Map<String, String>> da : data.entrySet()) {
			int rowID = Integer.parseInt(da.getKey());
			if (rowID > max)
				max = rowID;
		}
		String aa = getAllFieldName();
		String[] bb = aa.split(":");
		int lengthBB = bb.length;
		for (int i = 0; i < lengthBB; i++) {
			temp.put(bb[i], " ");
		}
		for (int i = 0; i < length1; i++) {
			// if (fieldExit(fieldName[i]))
			// {
			System.out.println(className + methodName + "tam: " + tam);

			System.out.println(className + methodName + "i: " + i);

			System.out.println(className + methodName + "fieldName[i]: "
					+ fieldName[i]);

			temp.put(fieldName[i], fieldValue[i]);
			if (isPrimaryKey(fieldName[i]))
				tam += fieldValue[i];
			// }

		}
		System.out.println(className + methodName + "tam: " + tam);
		System.out.println(className + methodName + "dub: " + dub);

		if (dub.containsKey(tam)) {
			return -23;
		}

		System.out.println(className + methodName + "data 1: " + data);

		data.put(max + 1 + "", temp);
		System.out.println(className + methodName + "data 2: " + data);
		return 1;
	}

	public void editRecord(int idx, String tableName, String fieldName,
			String fieldValue) {
		// TODO Auto-generated method stub
		Map<String, String> temp = new HashMap<String, String>();
		temp.putAll(data.get(idx + ""));
		temp.put(fieldName, fieldValue);
		data.put(idx + "", temp);
	}

	public void removeField(String fieldName) {
		// TODO Auto-generated method stub
		_fields.remove(fieldName);
	}

	public void removeTableFieldData(String fieldName) {
		// TODO Auto-generated method stub
		final String methodName = "removeTableFieldData:";
		if (data == null)
			return;
		int length = data.size();
		System.out.println(className + methodName + "data 1: " + data);
		for (Map.Entry<String, Map<String, String>> dd : data.entrySet()) {
			Map<String, Map<String, String>> a = new HashMap<String, Map<String, String>>();
			Map<String, String> temp = new HashMap<String, String>();
			temp.putAll(dd.getValue());
			System.out.println(className + methodName + "temp 1: " + temp);
			temp.remove(fieldName);
			System.out.println(className + methodName + "temp 2: " + temp);
			System.out.println(className + methodName + "temp.size:"
					+ temp.size());
			if (temp.size() == 0) {
				data.clear();
				return;
			} else {
				a.put(dd.getKey(), temp);
				data.put(dd.getKey(), a.get(dd.getKey()));
			}
			System.out.println(className + methodName + "data 2: " + data);

		}

	}

	public void renameAllRecord(String fieldName, String fieldNameNew) {
		// TODO Auto-generated method stub
		final String methodName = "renameAllRecord():";
		int length = data.size();
		System.out.println(className + methodName + "data 1: " + data);

		for (int i = 0; i < length; i++) {
			System.out.println(className + methodName + "i : " + i);

			Map<String, Map<String, String>> a = new HashMap<String, Map<String, String>>();
			Map<String, String> temp = new HashMap<String, String>();

			temp.putAll(getRow(i).get(i + ""));
			System.out.println(className + methodName + "temp 1: " + temp);

			String value = temp.get(fieldName);
			temp.remove(fieldName);
			temp.put(fieldNameNew, value);
			System.out.println(className + methodName + "temp 2: " + temp);
			System.out.println(className + methodName + "temp.size:"
					+ temp.size());

			a.put("" + i, temp);

			data.put(i + "", a.get(i + ""));
		}
		System.out.println(className + methodName + "data 2: " + data);

	}

	public void setPrimaryKey(Vector keys) {
		// TODO Auto-generated method stub
		if (keys == null) {
			primaryKey = null;
			return;
		}
		int length = keys.size();
		primaryKey = new String[length];
		for (int i = 0; i < length; i++) {
			primaryKey[i] = (String) keys.get(i);
		}
	}

	public Vector<String> getPrimaryKey() {
		Vector<String> result = new Vector<>();
		if (primaryKey == null)
			return null;
		int length = primaryKey.length;
		for (int i = 0; i < length; i++) {
			result.add(primaryKey[i]);
		}

		return result;
	}

	public void removePrimaryKey() {
		// TODO Auto-generated method stub
		primaryKey = null;
	}

	public void deleteRecord(String rowID) {
		// TODO Auto-generated method stub
		final String methodName = "deleteRecord():";
		System.out.println(className + methodName + "vao 0");

		if (data.containsKey(rowID)) {
			data.remove(rowID);
		}
		int length = data.size();
		if ((length + "").equals(rowID)) {
			return;
		}
		System.out.println(className + methodName + "vao 1");
		System.out.println(className + methodName + "data 0: " + data);

		Map<String, String> temp = data.get((length) + "");
		System.out.println(className + methodName + "temp 0: " + temp);

		data.remove((length) + "");
		System.out.println(className + methodName + "data 1: " + data);

		data.put(rowID, temp);
		System.out.println(className + methodName + "data 2: " + data);

	}
}
